using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Win32;

namespace RunShellCommands
{
	/// <summary>
	/// Interaction logic for Window1.xaml
	/// </summary>
	public partial class MainWindow
	{
		/// <summary>
		/// 
		/// </summary>
		private WindowState _lastWindowState;

		/// <summary>
		/// 
		/// </summary>
		private bool _shouldClose;

		/// <summary>
		/// 
		/// </summary>
		public MainWindow()
		{
			this.InitializeComponent();
			this.FillCommands();
		}

		/// <summary>
		/// Raises the <see cref="E:System.Windows.Window.StateChanged"/> event.
		/// </summary>
		/// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
		protected override void OnStateChanged(EventArgs e)
		{
			this._lastWindowState = this.WindowState;
		}

		/// <summary>
		/// Raises the <see cref="E:System.Windows.Window.Closing"/> event.
		/// </summary>
		/// <param name="e">A <see cref="T:System.ComponentModel.CancelEventArgs"/> that contains the event data.</param>
		protected override void OnClosing(CancelEventArgs e)
		{
			if (!this._shouldClose)
			{
				e.Cancel = true;
				this.Hide();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void OnSystemTrayIconDoubleClick(object sender, MouseButtonEventArgs e)
		{
			if (e.ChangedButton == MouseButton.Left)
				this.Open();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void OnMenuItemOpenClick(object sender, EventArgs e)
		{
			this.Open();
		}

		/// <summary>
		/// 
		/// </summary>
		private void Open()
		{
			this.Show();
			this.WindowState = this._lastWindowState;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void OnMenuItemExitClick(object sender, EventArgs e)
		{
			this._shouldClose = true;
			this.Close();
		}

		/// <summary>
		/// Fill Grid with shell command
		/// </summary>
		private void FillCommands()
		{
			OperatingSystem os = Environment.OSVersion;

			string registryPath = string.Empty;
			bool lookForSubKey = false;

			switch (os.Version.Major)
			{
				case 5: // 2000 - XP
					registryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders";
					break;
				case 6: // Vista - Seven
					registryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions";
					lookForSubKey = true;
					break;
				default:
					break;
			}

			RegistryKey regHklmRootKey = Registry.LocalMachine.OpenSubKey(registryPath);

			string[] shellCommands = new string[] {};

			if (lookForSubKey)
			{
				if (regHklmRootKey != null)
				{
					string[] subKeys = regHklmRootKey.GetSubKeyNames();

					shellCommands = new string[regHklmRootKey.SubKeyCount];

					for (int i = 0; i < subKeys.Length; i++)
					{
						string subKeyName = subKeys[i];

						RegistryKey regSubKey = regHklmRootKey.OpenSubKey(subKeyName);

						if (regSubKey != null)
							shellCommands[i] = regSubKey.GetValue("Name") as string;
					}
				}
			}
			else
			{
				// HKLM
				if (regHklmRootKey != null)
				{
					string[] hKlmShellCommands = regHklmRootKey.GetValueNames();
					// HKCU
					RegistryKey regHkcuRootKey = Registry.CurrentUser.OpenSubKey(registryPath);
					if (regHkcuRootKey != null)
					{
						string[] hKcuShellCommands = regHkcuRootKey.GetValueNames();

						shellCommands = new string[hKlmShellCommands.Length + hKcuShellCommands.Length];

						hKlmShellCommands.CopyTo(shellCommands, 0);
						hKcuShellCommands.CopyTo(shellCommands, hKlmShellCommands.Length);
					}
				}
			}

			Array.Sort(shellCommands);
			this.lbCommands.ItemsSource = shellCommands;

			// fill menu
			//MenuItem newMenu = new MenuItem("-");
			//this.MainMenu.MenuItems.Insert(0, newMenu);

			//foreach (string shellCommand in shellCommands)
			//{
			//    newMenu = new MenuItem(shellCommand, new EventHandler(OnMenuItemRunCommandClick));

			//    this.MainMenu.MenuItems.Insert(0, newMenu);
			//}

			//this.MainMenu.BuildContextMenu();

			MenuItem newMenu;

			foreach (string shellCommand in shellCommands)
			{
				newMenu = new MenuItem {Header = shellCommand};
				newMenu.Click += this.OnMenuItemRunCommandClick;

				this.MyNotifyIcon.ContextMenu.Items.Insert(0, newMenu);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void OnMenuItemRunCommandClick(object sender, EventArgs e)
		{
			string shellCommand = ((MenuItem)sender).Header.ToString();

			this.RunShellCommand(shellCommand);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void LbCommandsSelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			string shellCommand = (string)this.lbCommands.SelectedValue;

			this.RunShellCommand(shellCommand);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="shellCommand"></param>
		private void RunShellCommand(string shellCommand)
		{
			Process.Start("explorer.exe", "shell:" + shellCommand);
		}
	}
}